<script setup lang="ts">
import { type PropType, ref } from "vue";
import type { ToolInstallState } from "@/pages/tools/common/types";
import { hc } from "@/framework/vue/util/render";
import { DownloadOutlined, LoadingOutlined } from "@ant-design/icons-vue";
import path from "path-browserify-esm";
import { existsFile } from "@/framework/util/fs";
import { message, Modal } from "ant-design-vue";
import { download, downloadAndUnzip, installArchiveFile } from "@/pages/tools/common/util";
import type { UnzipCompleteArgs } from "@common/archives-file-types";
import { openExternal } from "@/framework/util/shell";

/* exe/msi安装包安装 */
defineOptions({ name: "installer-install-operation" });
const props = defineProps({
  // ID标识
  id: { type: String, required: true },
  // 是否已安装
  isInstalled: { type: Boolean, default: false },
  // 下载连接
  downloadUrl: { type: String, required: true },
  // 下载文件本地保存路径(压缩包文件的绝对路径)
  savePath: { type: String, required: true },
  // 安装完成回调参数
  callbackArgs: { type: [Object, Array, Number, Boolean, String, BigInt] as PropType<any> },
  // 安装完成回调
  installCallback: { type: Function as PropType<(args: any, localFile: string) => void> },
  installButtonText: { type: String, default: "安装" },
});

const state = ref<ToolInstallState>("initial");
const downloading = ref(false);
const downloadPercent = ref(0);

async function handleInstall() {
  if (downloading.value) return;
  const localFile = props.savePath;
  const exists = await existsFile(localFile);
  if (exists) {
    message.info("文件已下载");
    handleInstallLocal(localFile);
    return;
  }

  downloading.value = true;
  downloadPercent.value = 0;

  state.value = "downloading";
  try {
    const res = await download({
      id: props.id,
      url: props.downloadUrl,
      savePath: localFile,
      progress: e => (downloadPercent.value = Math.floor(e.percent * 100)),
    });
    downloading.value = false;
    handleInstallLocal(res.filePath);
  } catch (e: any) {
    message.error(e.message);
    state.value = "initial";
  } finally {
    downloading.value = false;
  }
}

function handleInstallLocal(localFile: string) {
  openExternal(localFile);
  if (typeof props.installCallback === "function") {
    state.value = "installing";
    Modal.confirm({
      centered: true,
      title: "安装",
      content: "已完成安装？(在弹出的安装窗口手动安装完成后点击)",
      onOk: () => props.installCallback?.(props.callbackArgs, localFile),
      afterClose: () => (state.value = "initial"),
    });
  }
}
</script>

<template>
  <span v-if="isInstalled" class="color-gray ph-8">已安装</span>
  <template v-else>
    <a-button v-if="state === 'initial'" type="text" size="small" :icon="hc(DownloadOutlined)" @click.stop="handleInstall"
      >{{ installButtonText }}
    </a-button>
    <a-space v-else-if="state === 'downloading'">
      <span>正在下载</span>
      <span>{{ downloadPercent }}%</span>
      <LoadingOutlined />
    </a-space>
    <a-space v-else>
      <span v-if="state === 'installing'">正在安装</span>
      <LoadingOutlined />
    </a-space>
  </template>
</template>
